package org.leo.dm.example.reader;

import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.dom4j.Element;
import org.dom4j.ElementHandler;
import org.dom4j.ElementPath;
import org.dom4j.io.SAXReader;
import org.leo.dm.common.bean.StepResultBean;
import org.leo.dm.component.reader.Reader;
import org.leo.dm.util.ToUtil;
import org.leo.dm.util.ZipBase64Util;

public class SaxXmlReader extends Reader implements ElementHandler {

	private String data;

	public void setData(String data) {
		this.data = data;
	}

	private boolean isContinue = true;

	private boolean isContinue() {
		return isContinue;
	}

	private void setContinue(boolean isContinue) {
		this.isContinue = isContinue;
	}

	@Override
	public StepResultBean call() {
		StepResultBean resultBean = new StepResultBean();
		try {
			InputStream gin = new ZipBase64Util().decode(data);

			ToUtil tuSax = new ToUtil();
			SAXReader sax = new SAXReader();
			sax.setDefaultHandler(this);
			sax.read(gin);
			tuSax.takeTimePrex("解析花费时间");

			Map<String, Object> callBackMap = new HashMap<String, Object>();
			callBackMap.put("counter", counter);
			callBack.handle(callBackMap);

			resultBean.setCode("1");
			resultBean.setName("运行正常完成");
			resultBean.setSuccessCount(counter);
		} catch (Exception e) {
			e.printStackTrace();
			resultBean.setCode("-1");
			resultBean.setName("运行发生异常");
			resultBean.setErrorDesc(e.getMessage());
			try {
				this.getFlow().stop();
			} catch (Exception e1) {
				e1.printStackTrace();
			}
		} finally {
			counter = 0;// 计数器清零
		}

		return resultBean;
	}

	@Override
	public void onStart(ElementPath elementPath) {
		if (isContinue()) {
			try {
				Element urlNode = elementPath.getCurrent();

				if ("data".equals(urlNode.getName())) {

					storage.putStartQueue(queuePlugin.handle(storage.getStorageName()), null);
					extendDataNamesLength = extendDataNames.length;
				}
				// urlNode.detach();
			} catch (Exception e) {
				e.printStackTrace();
				setContinue(false);
				try {
					this.getFlow().stop();
				} catch (Exception e1) {
					e1.printStackTrace();
				}
			}
		}
	}

	private String datacode;

	private final int extendDataNamesLengthDefault = 0;
	private int extendDataNamesLength = extendDataNamesLengthDefault;

	@Override
	public void onEnd(ElementPath elementPath) {
		if (isContinue()) {

			try {
				Element urlNode = elementPath.getCurrent();
				// log.info("onEnd:" + urlNode.asXML());
				if ("messages".equals(urlNode.getName())) {
					urlNode.detach();
				}
				if ("datasetcode".equals(urlNode.getName())) {
					datacode = urlNode.getText();
					segmentPlugin.handle(datacode);
					urlNode.detach();
				}
				if ("detail".equals(urlNode.getName())) {
					List<?> list = urlNode.elements();

					counter++;// 计数器累加
					seqmentcounter++;

					Element e = null;
					int listSize = list.size();

					dataValues = new String[listSize + extendDataNamesLength];
					for (int i = 0; i < listSize; i++) {
						e = (Element) list.get(i);
						dataValues[i] = columnPlugin.handle(datacode, e.getName(), e.getText());
					}

					// 代表当前数据集的第一条数据
					if (Integer.valueOf(seqmentcounter) == 1) {
						dataNames = new String[listSize + extendDataNamesLength];

						for (int i = 0; i < listSize; i++) {
							e = (Element) list.get(i);
							dataNames[i] = e.getName();
						}
						for (int i = listSize; i < listSize + extendDataNamesLength; i++) {
							dataNames[i] = extendDataNames[i - listSize];
						}
						storage.putStartSeqment(1, datacode, dataNames, null);
					}

					storage.putData(recordPlugin.handle(datacode, dataNames, dataValues, seqmentcounter));

					urlNode.detach();
				}
				if ("dataset".equals(urlNode.getName())) {
					seqmentcounter = 0;
					storage.putEndSeqment(1);
					urlNode.detach();
				}
				if ("data".equals(urlNode.getName())) {
					storage.putEndQueue();
					urlNode.detach();
				}
			} catch (Exception e) {
				e.printStackTrace();
				setContinue(false);
				try {
					this.getFlow().stop();
				} catch (Exception e1) {
					e1.printStackTrace();
				}
			}
		}
	}

}
